package com.freejy.ecommunity.common.word;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

@SuppressWarnings("all")
public class NgWordUtil {
	
    /** 直接禁止的 */
    private final static Map keysMap = new HashMap();
    private static int matchType = 1; // 1:最小长度匹配 2：最大长度匹配

    private static NgWordUtil instance = new NgWordUtil();
    
    private NgWordUtil(){
    	initfiltercode();
    }
    
    public static NgWordUtil getInstance(){
    	return instance;
    }
    
    private void addKeywords(Set<String> keywords) {
    	Iterator<String> iterator = keywords.iterator();  
        while (iterator.hasNext()) {
            String key = iterator.next().trim();
            Map nowhash = null;
            nowhash = keysMap;
            for (int j = 0; j < key.length(); j++) {
                char word = key.charAt(j);
                Object wordMap = nowhash.get(word);
                if (wordMap != null) {
                    nowhash = (HashMap) wordMap;
                } else {
                    HashMap<String, String> newWordHash = new HashMap<String, String>();
                    newWordHash.put("isEnd", "0");
                    nowhash.put(word, newWordHash);
                    nowhash = newWordHash;
                }
                if (j == key.length() - 1) {
                    nowhash.put("isEnd", "1");
                }
            }
        }
    }

    /**
     * 重置关键词
     */
    private void clearKeywords() {
        keysMap.clear();
    }

    /**
     * 检查一个字符串从begin位置起开始是否有keyword符合， 如果有符合的keyword值，返回值为匹配keyword的长度，否则返回零 flag 1:最小长度匹配 2：最大长度匹配
     */
    private int checkKeyWords(String txt, int begin, int flag) {
        Map nowhash = null;
        nowhash = keysMap;
        int maxMatchRes = 0;
        int res = 0;
        int l = txt.length();
        char word = 0;
        for (int i = begin; i < l; i++) {
            word = txt.charAt(i);
            Object wordMap = nowhash.get(word);
            if (wordMap != null) {
                res++;
                nowhash = (Map) wordMap;
                if (((String) nowhash.get("isEnd")).equals("1")) {
                    if (flag == 1) {
                        wordMap = null;
                        nowhash = null;
                        txt = null;
                        return res;
                    } else {
                        maxMatchRes = res;
                    }
                }
            } else {
                txt = null;
                nowhash = null;
                return maxMatchRes;
            }
        }
        txt = null;
        nowhash = null;
        return maxMatchRes;
    }

    /**
     * 返回txt中关键字的列表
     */
    public List<String> getTxtKeyWords(String txt) {
        List<String> list = new ArrayList<String>();
        int l = txt.length();
        for (int i = 0; i < l;) {
            int len = checkKeyWords(txt, i, matchType);
            if (len > 0) {
                String tt = "<font color='#ff0000'>" + txt.substring(i, i + len) + "</font>";
                list.add(tt);
                i += len;
            } else {
                i++;
            }
        }
        txt = null;
        return list;
    }

    /**
     * 用***过滤
     */
    public String doFilter(String txt) {
        StringBuffer sb = new StringBuffer(txt);
        int l = txt.length();

        for (int i = 0; i < l;) {
            int len = checkKeyWords(txt, i, matchType);
            if (len > 0) {
                sb.replace(i, i + len, StringUtils.repeat('*', len));
                i += len;
            } else {
                i++;
            }
        }
        txt = null;
        return sb.toString();
    }

    /**
     * 仅判断txt中是否有关键字
     */
    public boolean isContentKeyWords(String txt) {
        for (int i = 0; i < txt.length(); i++) {
            int len = checkKeyWords(txt, i, 1);
            if (len > 0) {
                return true;
            }
        }
        txt = null;
        return false;
    }

    /**
     * 初始化敏感词列表
     * */
    private void initfiltercode() {
    	Set<String> keywords = new HashSet<String>();

        InputStream in = NgWordUtil.class.getClassLoader().getResourceAsStream("words.properties");
        try
		{
			InputStreamReader read = new InputStreamReader(in, "UTF-8");
			BufferedReader bufferedReader = new BufferedReader(read);
			String txt = null;
			while ((txt = bufferedReader.readLine()) != null)
			{ //读取文件，将文件内容放入到set中
				keywords.add(txt);
			}
		} catch (Exception e)
		{
			e.printStackTrace();
		}
//        Properties pro = new Properties();
//        try {
//            pro.load(in);
//            in.close();
//        } catch (IOException e1) {
//            // can ignore.
//        }
//        Enumeration<String> enu = (Enumeration<String>) pro.propertyNames();
//        while (enu.hasMoreElements()) {
//            String dd = enu.nextElement();
//            keywords.add(dd);
//        }
        addKeywords(keywords);
    }

    private int getMatchType() {
        return matchType;
    }

    private void setMatchType(int matchType) {
        this.matchType = matchType;
    }

    public static void main(String[] args) throws IOException {

//        final KeywordFilter filter = new KeywordFilter();
//        filter.initfiltercode();
        final String txt = "百家乐她长孙家提携恩情，FL大法不会有人去追查这件事的，中南海权力斗争就一次，就一次，好吗？SM用品";
        final boolean boo = NgWordUtil.getInstance().isContentKeyWords(txt);
        System.out.println(boo);
        final List<String> set = NgWordUtil.getInstance().getTxtKeyWords(txt);
        System.out.println("包含的敏感词如下：" + set);
//        final Date date = new Date();
        final String ret = NgWordUtil.getInstance().doFilter(txt);
        System.out.println("替换后：" + ret);
//        final Date date2 = new Date();
//        final float ss = date2.getTime() - date.getTime();
//        System.out.println(ss + "毫秒");
    }
}
